/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 */

import React, { useEffect, ReactElement, useRef } from 'react';
import {
  StatusBar,
  BackHandler,
  DeviceEventEmitter,
  ToastAndroid,
  View
} from 'react-native';
import {
  createStackNavigator,
  createAppContainer,
  NavigationState,
  NavigationAction,
  TransitionConfig,
  StackViewTransitionConfigs,
  NavigationTransitionProps,
  NavigationScreenOptions,
  NavigationScreenConfigProps
} from 'react-navigation';
import codePush from 'react-native-code-push';
import BackgroundJob from 'react-native-background-job';

import Orientation from './util/native/orientation';
import routes from './routes';
import Modal from './components/Modal';
import ToolTip from './components/ToolTip';
import Loading from './components/Loading';
import Log from './common/log';
import navigator from './util/navigator';
import baseTracker from './common/baseTracker';
import tracker from './util/actionTracker';
import {
  NAVIGATION_COMPLETE_TRANSITION,
  CODE_PUSH_KEY,
  isIOS,
  SCREEN_WIDTH,
  SCREEN_HEIGHT,
  IS_TABLET_DEVICE
} from './constant';
import { routeToEvent } from './constant/events';
import netInfo from './common/netInfo';
import Provider from './reducer';
import { setRequestInfo } from './util/requestLifeCycle';
import styles from './style';
import { systemUtil, shellExec } from './util/native';
import inAppPurchaseModule from './util/native/inAppPurchaseModule';
import {
  REACT_NATIVE_REQUEST_TIME_INFO,
  REACT_NATIVE_WINDOW_CHANGED
} from './constant/nativeEvent';
import {
  PORTRAIT_ROUTES,
  getRouteType,
  RouteType,
  STATUS_BAR_LIGHT_ROUTES,
  NOT_SUPPORT_BACK_ROUTES
} from './config/route';
import statusBarManager from './util/native/statusBarManager';
import { startReceivePushMsg, stopReceivePushMsg } from './util/pushMsg';
import { startReceiveSEIMsg, stopReceiveSEIMsg } from './util/liveSEI';
import { loading } from './util/global';
import { getScreenInfo, ScreenOrientation } from './util/screen';
import { continueDownload } from './util/videoDownload/videoDownloadManage';
import httpServer from './util/native/httpServer';

let timer: NodeJS.Timer | null;
let haveHandleBack = false;

const HOME_HANDLE_BACK_TIME = 3001;

const { width } = getScreenInfo({
  screenOrientation: ScreenOrientation.Portrait
});

const screenWidth = Math.min(SCREEN_WIDTH, SCREEN_HEIGHT);

const marginHorizontal = (screenWidth - width) / 2;

export const backgroundJob = {
  jobKey: 'continueDownload',
  job: continueDownload
};

BackgroundJob.register(backgroundJob);

const codePushOptions = {
  checkFrequency: codePush.CheckFrequency.MANUAL,
  deploymentKey: CODE_PUSH_KEY
};

const initConfig = {
  initialRouteName: 'Entrance',
  defaultNavigationOptions: (
    navigationOptionsContainer: NavigationScreenConfigProps
  ): NavigationScreenOptions => {
    const notSupportBack = !!NOT_SUPPORT_BACK_ROUTES.find(
      (item): boolean =>
        item === navigationOptionsContainer.navigation.state.routeName
    );
    if (isIOS && notSupportBack) {
      return {
        header: null,
        gesturesEnabled: false
      };
    }

    return {
      header: null,
      gesturesEnabled: true
    };
  },
  transitionConfig: (
    transitionProps: NavigationTransitionProps,
    prevTransitionProps: NavigationTransitionProps
  ): TransitionConfig => {
    if (transitionProps) {
      const { routeName } = transitionProps.scene.route;
      const routeType = getRouteType(routeName);

      if (routeName === 'Login') {
        return StackViewTransitionConfigs.ModalSlideFromBottomIOS;
      }

      if (routeType === RouteType.LandScape) {
        return StackViewTransitionConfigs.FadeOutToBottomAndroid;
      }
    }
    if (prevTransitionProps) {
      const { routeName } = transitionProps.scene.route;

      if (routeName === 'Login') {
        return StackViewTransitionConfigs.ModalSlideFromBottomIOS;
      }
    }
    return StackViewTransitionConfigs.SlideFromRightIOS;
  }
};

// 路由
const AppNavigator = createStackNavigator(routes, initConfig);

const AppContainer = createAppContainer(AppNavigator);

// 入口
const Entrance = (): ReactElement => {
  const view = useRef<View>(null);

  // 返回true禁用安卓返回物理（或虚拟）返回键
  const handleBackButton = (): boolean => {
    const routeList = navigator.getRouteList();

    if (routeList && routeList.length === 1) {
      if (haveHandleBack) {
        haveHandleBack = false;
        systemUtil.exitApp();
        return true;
      }
      ToastAndroid.show('再按一次将退出蜜蜂小班', HOME_HANDLE_BACK_TIME);
      haveHandleBack = true;
      timer = setTimeout((): void => {
        haveHandleBack = false;
      }, HOME_HANDLE_BACK_TIME);
      return true;
    }
    loading.hide();
    return false;
  };

  useEffect((): (() => void) => {
    // 观察日志，调整dns超时时间（默认：2000ms）限制，使用本地缓存时间（默认：2000ms）限制
    // NativeModules.ConstantModule.putInt(
    //   'useLocalCacheTimeout',
    //   10000,
    //   'IP_INFO'
    // );

    // NativeModules.ConstantModule.putInt('dnsTimeout', 100, 'IP_INFO');

    shellExec.setBackupIPs('47.98.208.245', 'devapi.mifengxiaoban.com');
    shellExec.setBackupIPs('47.98.208.245', 'api.mifengxiaoban.com');
    httpServer.create();

    systemUtil.showNavigationBar();
    if (!isIOS) {
      StatusBar.setBackgroundColor('transparent');
    }

    StatusBar.setHidden(false, 'fade');
    Orientation.lockToPortrait();

    BackHandler.addEventListener('hardwareBackPress', handleBackButton);
    netInfo.start();

    // 检测请求耗时
    const subscription = DeviceEventEmitter.addListener(
      REACT_NATIVE_REQUEST_TIME_INFO,
      setRequestInfo
    );

    const windowChangedSubscription = DeviceEventEmitter.addListener(
      REACT_NATIVE_WINDOW_CHANGED,
      ({ hasFocus }): void => {
        const haveCurrentRoute = navigator.haveCurrentRoute();

        if (!haveCurrentRoute) {
          return;
        }
        const currentRoute = navigator.getCurrentRoute().routeName;

        if (
          hasFocus &&
          !PORTRAIT_ROUTES.find((item): boolean => item === currentRoute)
        ) {
          Orientation.lockToLandscape();
          systemUtil.hideNavigationBar();
        }
      }
    );

    inAppPurchaseModule.addEventEmitter();

    systemUtil.getAliPayInstalled();

    startReceivePushMsg();
    startReceiveSEIMsg();

    return (): void => {
      if (timer) {
        clearTimeout(timer);
        timer = null;
      }

      BackHandler.removeEventListener('hardwareBackPress', handleBackButton);
      baseTracker.stop();
      netInfo.stop();

      inAppPurchaseModule.removeEventEmitter();

      stopReceivePushMsg();
      stopReceiveSEIMsg();

      if (subscription) {
        subscription.remove();
      }

      if (windowChangedSubscription) {
        windowChangedSubscription.remove();
      }
    };
  }, []);

  const updateViewProps = (v: number): void => {
    if (view && view.current && IS_TABLET_DEVICE) {
      view.current.setNativeProps({
        style: { marginHorizontal: v }
      });
    }
  };

  const onNavigationStateChange = (
    prevNavigationState: NavigationState,
    nextNavigationState: NavigationState,
    action: NavigationAction
  ): void => {
    if (action.type === NAVIGATION_COMPLETE_TRANSITION) {
      return;
    }

    Log.i(
      'navigatorState',
      JSON.stringify({
        nextNavigationState,
        action: action.type
      })
    );

    const routeNames = nextNavigationState.routes.map(
      (item): string => item.routeName
    );

    const prevRouteNames = prevNavigationState.routes.map(
      (item): string => item.routeName
    );

    if (routeNames.length === 0 || prevRouteNames.length === 0) {
      return;
    }

    const currentRouteType = getRouteType(routeNames[routeNames.length - 1]);
    const prevRouteType = getRouteType(
      prevRouteNames[prevRouteNames.length - 1]
    );

    // 横竖屏切换，各个状态切换
    if (
      currentRouteType === RouteType.LandScape &&
      prevRouteType === RouteType.Portrait
    ) {
      StatusBar.setHidden(true, 'fade');

      Orientation.lockToLandscape();

      systemUtil.hideNavigationBar();

      updateViewProps(0);
    } else if (
      currentRouteType === RouteType.Portrait &&
      prevRouteType === RouteType.LandScape
    ) {
      systemUtil.showNavigationBar();
      if (!isIOS) {
        StatusBar.setBackgroundColor('transparent');
      }

      StatusBar.setHidden(false, 'fade');
      Orientation.lockToPortrait();

      updateViewProps(marginHorizontal);
    }

    // 设置当前路由数组
    navigator.setRoutes(nextNavigationState.routes);

    const currentRoute = routeToEvent[routeNames[routeNames.length - 1]];

    // 不同页面，状态栏颜色不一样
    if (
      STATUS_BAR_LIGHT_ROUTES.find(
        (item): boolean => item === routeNames[routeNames.length - 1]
      )
    ) {
      statusBarManager.setBarStyle('light-content', true);
    } else {
      statusBarManager.setBarStyle('dark-content', true);
    }

    if (currentRoute) {
      tracker.reportAction(currentRoute);
    }
  };

  return (
    <Provider>
      <View style={styles.container} ref={view}>
        <AppContainer
          ref={(nav): void => {
            navigator.setTopLevelNavigator(nav);
          }}
          onNavigationStateChange={onNavigationStateChange}
        />

        {/* 全局组建列表 */}
        <Modal />
        <ToolTip />
        <Loading />
      </View>
    </Provider>
  );
};

export default codePush(codePushOptions)(Entrance);
